﻿using BattleFury.Lib.Network;
using BattleFury.Lib.Network.Events;
using BattleFury.Lib.Network.Packets;
using Lidgren.Network;
using System;

namespace BattleFury.Console
{
	class Program
	{
		public static bool IsRunning = true;
		public static string Prompt = "> ";
		public static string AppIdentifier = "Fury";
		public static string Host = "localhost";
		public static int Port = 28657;
		public static NetworkClient Client;
		public static char Delimiter = ':';
		
		static void Main(string[] args)
		{
			WriteLine("BattleFury Debug Console Client");
			WriteLine("-------------------------------");
			WriteLine("CONN to connect");
			WriteLine("-------------------------------");
			while (IsRunning)
			{
				Write(Prompt);
				ProcessInput();
			}	
		}
		
		#region Methods

		public static void Write(string format, params object[] args)
		{
			System.Console.Write(format, args);
		}

		public static void WriteLine(string format, params object[] args)
		{
			System.Console.WriteLine(format, args);
		}

		public static void ProcessInput()
		{
			var input = System.Console.ReadLine();
			input = input.ToLower();

			if (input == "exit")
			{
				IsRunning = false;
				return;
			}
			if (input == "conn")
			{
				WriteLine("Connecting to {0}:{1}", Host, Port);
				Connect();
				return;
			}
			if (input == "disc")
			{
				WriteLine("Disconnecting from {0}:{1}", Host, Port);
				Disconnect();
				return;
			}
			if(input.StartsWith("msg"))
			{
				var split = input.Split(Delimiter);
				SendMessage(split[1]);
				return;
			}
			if (input.StartsWith("delimiter"))
			{
				var split = input.Split(Delimiter);
				Delimiter = Convert.ToChar(split[1]);
				WriteLine("Delimiter changed to {0}", Delimiter);
				return;
			}

			if (Client == null || (Client != null && Client.Status == NetConnectionStatus.Disconnected))
			{
				WriteLine("Unknown command: {0}", input);
			}
			else
			{
				SendMessage(input);
			}
		}

		#endregion
		
		#region Actions

		public static void Connect()
		{
			if (Client != null && Client.Status == NetConnectionStatus.Connected)
			{
				WriteLine("Already connected to {0}:{1}", Host, Port);
				return;
			}

			try
			{
				Client = new NetworkClient(AppIdentifier, Host, Port);
				Client.OnMessageReceived += OnMessageReceived;
				Client.Connect();
				
				
				WriteLine("Connected to {0}:{1}", Host, Port);
			}
			catch (Exception e)
			{
				System.Console.WriteLine(e);
			}
		}

		private static void OnMessageReceived(object sender, MessageReceivedEventArgs e)
		{
			WriteLine(e.Message);
			Write(Prompt);
		}

		public static void Disconnect()
		{
			if (Client != null && Client.Status == NetConnectionStatus.Disconnected)
			{
				WriteLine("Already disconnected from {0}:{1}", Host, Port);
				return;
			}

			try
			{
				Client.Disconnect();
				WriteLine("Disconnected from {0}:{1}", Host, Port);
			}
			catch (Exception e)
			{
				System.Console.WriteLine(e);
			}
		}

		public static void SendMessage(string message)
		{
			if (Client == null)
			{
				WriteLine("Not connected to a server");
				return;
			}

			if (Client != null && Client.Status == NetConnectionStatus.Disconnected)
			{
				WriteLine("Not connected to a server");
				return;
			}

			try
			{
				var packet = new MessagePacket
				{
					Message = message
				};
				Client.SendPacket(packet);
			}
			catch (Exception e)
			{
				System.Console.WriteLine(e);
			}
		}

		#endregion

	}
}